use std::default::Default;
use crate::chess::PieceColor;

#[derive(Debug, Clone)]
pub enum PointState {
    Kill,
    Piece(PieceColor)
}

#[derive(Debug)]
pub struct Point<'p> {
    id: u8,
    piece: Option<PointState>,
    v: &'p Edge<'p>,
    h: &'p Edge<'p>,
}

impl <'p> Point<'p> {
    pub fn new(id: u8) -> Point<'p> {
        Point{
            id,
            piece: None,
            h: &Edge::default(),
            v: &Edge::default(),
        }
    }

    pub fn set_edge(&mut self, h: &'p Edge, v: &'p Edge) {
        self.h = h;
        self.v = v;
    }
}



#[derive(Debug)]
pub struct Edge<'e> {
    point: Vec<&'e Point<'e>>,
}

impl <'e> Edge<'e> {
    pub fn new(left: &'e Point, center: &'e Point, right: &'e Point) -> Edge<'e> {
        Edge{
            point: vec![left, center, right]
        }
    }
}

impl <'e> Default for Edge<'e> {
    fn default() -> Self {
        Edge{
            point: vec![]
        }
    }
}

pub struct Chessboard<'c> {
    points: Vec<&'c Point<'c>>,
    lines: Vec<&'c Edge<'c>>,
}

impl <'c> Chessboard<'c> {
    pub fn new() -> Chessboard<'c> {
        let mut points = Vec::<&'c Point>::with_capacity(24);
        for i in 0..=24 {
            points[i] = &Point::new(i as u8);
        }
        let l01 = Edge::new(&points[0], &points[1], &points[2]);
        let l02 = Edge::new(&points[2], &points[3], &points[4]);
        let l03 = Edge::new(&points[4], &points[5], &points[6]);
        let l04 = Edge::new(&points[6], &points[7], &points[0]);
        let l05 = Edge::new(&points[8], &points[9], &points[10]);
        let l06 = Edge::new(&points[10], &points[11], &points[12]);
        let l07 = Edge::new(&points[12], &points[13], &points[14]);
        let l08 = Edge::new(&points[14], &points[15], &points[8]);
        let l09 = Edge::new(&points[16], &points[17], &points[18]);
        let l10 = Edge::new(&points[18], &points[19], &points[20]);
        let l11 = Edge::new(&points[20], &points[21], &points[22]);
        let l12 = Edge::new(&points[22], &points[23], &points[16]);
        let l13 = Edge::new(&points[1], &points[9], &points[17]);
        let l14 = Edge::new(&points[3], &points[11], &points[19]);
        let l15 = Edge::new(&points[5], &points[13], &points[21]);
        let l16 = Edge::new(&points[7], &points[15], &points[23]);

        points[0].set_edge(&l01, &l04);
        points[1].set_edge(&l01, &l13);
        points[2].set_edge(&l01, &l02);
        points[3].set_edge(&l02, &l14);
        points[4].set_edge(&l02, &l03);
        points[5].set_edge(&l03, &l15);
        points[6].set_edge(&l03, &l04);
        points[7].set_edge(&l04, &l16);
        points[8].set_edge(&l05, &l08);
        points[9].set_edge(&l05, &l13);
        points[10].set_edge(&l06, &l05);
        points[11].set_edge(&l06, &l14);
        points[12].set_edge(&l07, &l06);
        points[13].set_edge(&l07, &l15);
        points[14].set_edge(&l08, &l07);
        points[15].set_edge(&l08, &l16);
        points[16].set_edge(&l09, &l12);
        points[17].set_edge(&l09, &l13);
        points[18].set_edge(&l10, &l09);
        points[19].set_edge(&l10, &l14);
        points[20].set_edge(&l11, &l10);
        points[21].set_edge(&l11, &l15);
        points[22].set_edge(&l12, &l11);
        points[23].set_edge(&l12, &l16);

        Chessboard{
            points,
            lines: vec![&l01, &l02, &l03, &l04, &l05, &l06, &l07, &l08, &l09, &l10, &l11, &l12, &l13, &l14, &l15, &l16],
        }
    }
}